package com.minivision.fdiot.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.google.common.util.concurrent.RateLimiter;
import com.minivision.fdiot.exception.ServiceException;
import com.minivision.fdiot.rate.algorithm.RateLimitingAlgorithm;
import com.minivision.fdiot.rate.config.RateLimitingProperties;

/**
 * API限流拦截器
 * @author hughzhao
 * @2018年3月1日
 */
@Component
public class RateLimitingInterceptor extends HandlerInterceptorAdapter {

	private final RateLimitingAlgorithm rateLimitingAlgorithm;
	
	private final RateLimitingProperties rateLimitingProperties;
	
	private RateLimiter rateLimiter;

	@Autowired
	public RateLimitingInterceptor(RateLimitingAlgorithm rateLimitingAlgorithm, RateLimitingProperties rateLimitingProperties){
		this.rateLimitingAlgorithm = rateLimitingAlgorithm;
		this.rateLimitingProperties = rateLimitingProperties;
		rateLimiter = RateLimiter.create(rateLimitingProperties.getPermitsPerSecond());
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
	    if (rateLimitingProperties.isLimiterEnabled()) {
	        rateLimiter.acquire();
        }
		boolean canContinue = rateLimitingAlgorithm.process(request);
		if (!canContinue) {
		    throw new ServiceException(rateLimitingProperties.getExceedMessage());
		} else {
			return true;
		}
	}
	
}
